package com.visionet.waveletData.web.common.security.password;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.visionet.waveletData.web.common.utilities.props.PropsKeys;
import com.visionet.waveletData.web.common.utilities.props.PropsUtil;
import com.visionet.waveletData.web.vo.SignVo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.TreeMap;

/**
 * Created by hxpeng on 2017/2/13.
 */
public final class RequestSignUtil {

    private static Logger logger = LoggerFactory.getLogger(RequestSignUtil.class);

    private static final String EQUAL_SIGN = ":";
    private static final String AND_SIGN = ",";

    private static String localAppkey = PropsUtil.getProperty(PropsKeys.LOCAL_SIGN_Key);
    private static String localApptoken = PropsUtil.getProperty(PropsKeys.LOCAL_SIGN_Token);

    private static String appkey = PropsUtil.getProperty(PropsKeys.SIGN_Key);
    private static String apptoken = PropsUtil.getProperty(PropsKeys.SIGN_Token);

    public static String sign(JSONObject params, long currentTime) throws Exception {
        logger.debug("params:" + (params == null ? "null" : params.toJSONString()));
        logger.debug("currentTime:" + currentTime);
        StringBuilder builder = new StringBuilder();
        if(params != null)
            builder.append(buildParam(params)).append(",");
        builder.append("time:").append(currentTime).append(",");
        builder.append("appkey:").append(appkey).append(",");
        builder.append("apptoken:").append(apptoken);
        return Md5Encoder.encoding(builder.toString()).toString();
    }

    private static String buildParam(JSONObject params) {
        String original = sortParams(params);
        String result = original.substring(1, original.length() - 1);
        return result.replaceAll("\"", "");
    }

    private static String sortParams(JSONObject params) {
        if (params != null) {
            return JSONObject.toJSONString(params);
        }
        return "";
    }

    public static String createSign(long currentTime){
        String sign = null;
        try {
            sign = sign(null, currentTime);
        } catch (Exception e) {
            logger.error("生成签名出错", e);
            throw new RuntimeException("生成签名出错", e);
        }
        return sign;
    }


    public static boolean checkSignByJSON(JSONObject jsonObject){

        try{
            String signVoStr = jsonObject.getString("system");
            SignVo signVo = JSON.parseObject(signVoStr,SignVo.class);
            StringBuffer sb = new StringBuffer();
            TreeMap<String, String> treeMap = new TreeMap<String, String>();
            for(String s : jsonObject.keySet()){
                if(!"system".equals(s)){
                    treeMap.put(s,jsonObject.getString(s));
                }
            }
            for (String key : treeMap.keySet()) {
                String value = treeMap.get(key);
                if(StringUtils.isNotBlank(value)){
                    sb.append(key);
                    sb.append(EQUAL_SIGN);
                    sb.append(value);
                    sb.append(AND_SIGN);
                }
            }
            sb.append("time").append(EQUAL_SIGN).append(signVo.getTime()).append(AND_SIGN);
            sb.append("appkey").append(EQUAL_SIGN).append(localAppkey).append(AND_SIGN);
            sb.append("apptoken").append(EQUAL_SIGN).append(localApptoken);
            System.out.println(sb.toString());
            String sign = MD5(sb.toString());
            System.out.println(sign);
            if(sign.equals(signVo.getSign())){
                return true;
            }else{
                return false;
            }
        }catch (Exception e){
            logger.error("解析签名异常:" + e.getMessage());
            return false;
        }
    }

    public static String createCurdPlayPlanSign(TreeMap<String,String> treeMap){
        long currentDate = new Date().getTime()/1000;
        StringBuffer sb = new StringBuffer();
        for (String key : treeMap.keySet()) {
            String value = treeMap.get(key);
            if(StringUtils.isNotBlank(value)){
                sb.append(key);
                sb.append(EQUAL_SIGN);
                sb.append(value);
                sb.append(AND_SIGN);
            }
        }
        sb.append("time").append(EQUAL_SIGN).append(currentDate).append(AND_SIGN);
        sb.append("appkey").append(EQUAL_SIGN).append(appkey).append(AND_SIGN);
        sb.append("apptoken").append(EQUAL_SIGN).append(apptoken);
        System.out.println("========================================================");
        System.out.println(sb.toString());
        System.out.println("========================================================");
        String sign = MD5(sb.toString());
        SignVo signVo = new SignVo();
        signVo.setSign(sign);
        signVo.setAppkey(appkey);
        signVo.setTime(currentDate);
        return JSONObject.toJSONString(signVo);
    }


    public static final void main(String args[]){
        String s = "{\"companyId\":\"001\",\"createDate\":1487660679000,\"isDeleted\":false,\"planId\":\"124\",\"planName\":\"牌楼播放机\",\"robotList\":[{\"robotNumber\":\"PB0004\"},{\"robotNumber\":\"PB0005\"},{\"robotNumber\":\"PB0006\"}],\"updateDate\":1487837965000,\"videoList\":[{\"createBy\":\"admin\",\"createDate\":1487747718000,\"endTime\":1488124799000,\"fileName\":\"萌萌哒天团 - 帝都\",\"filePath\":\"f1709b1808712997040f241edb19be07\",\"fileSize\":14553389,\"fileType\":\"mp4\",\"id\":157,\"is_deleted\":\"0\",\"planId\":\"124\",\"startTime\":1487692800000,\"updateBy\":\"admin\",\"updateDate\":1487747718000},{\"createBy\":\"admin\",\"createDate\":1487756266000,\"endTime\":1487865599000,\"fileName\":\"胜屿 - 该死的懦弱\",\"filePath\":\"a60527c6fa5a10e882179d50c4a3efb6\",\"fileSize\":19384000,\"fileType\":\"avi\",\"id\":158,\"is_deleted\":\"0\",\"planId\":\"124\",\"startTime\":1487692800000,\"updateBy\":\"admin\",\"updateDate\":1487756266000},{\"createBy\":\"admin\",\"createDate\":1487767356000,\"endTime\":1487951999000,\"fileMd5\":\"8F879CB8894DC9BE084FB2011096C9F5\",\"fileName\":\"哈哈哈哈\",\"filePath\":\"cb4c99e571b5ed5e3ad4b8e33fcd2f1b\",\"fileSize\":2689032,\"fileType\":\"MOV\",\"id\":161,\"is_deleted\":\"0\",\"planId\":\"124\",\"startTime\":1487692800000,\"updateBy\":\"admin\",\"updateDate\":1487767356000}]}";
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("playPlan",s);

        SignVo signVo = new SignVo();
        signVo.setTime(1487837965l);
        signVo.setSign("c22041b471cc6695eff2a1b97c790c4c");

        jsonObject.put("system",JSONObject.toJSONString(signVo));

        System.out.print("结果==============="+checkSignByJSON(jsonObject));

    }


    /**
     * MD5加密
     * @param sourceStr
     * @return
     */
    private static String MD5(String sourceStr) {
        String result = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(sourceStr.getBytes());
            byte b[] = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            result = buf.toString();
        } catch (NoSuchAlgorithmException e) {
            System.out.println(e);
        }
        return result;
    }

}
